package com.uniflow.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 数据同步日志实体类
 */
@ApiModel(description = "数据同步日志")
@TableName("data_sync_log")
public class DataSyncLog {
    
    @ApiModelProperty("日志ID")
    @TableId(type = IdType.ASSIGN_ID)
    private String id;
    
    @ApiModelProperty("同步任务ID")
    private String syncId;
    
    @ApiModelProperty("同步任务名称")
    private String syncName;
    
    @ApiModelProperty("执行批次号")
    private String batchNo;
    
    @ApiModelProperty("开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime startTime;
    
    @ApiModelProperty("结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endTime;
    
    @ApiModelProperty("执行耗时（毫秒）")
    private Long duration;
    
    @ApiModelProperty("执行状态：running-运行中，success-成功，failed-失败，cancelled-已取消")
    private String status;
    
    @ApiModelProperty("执行结果")
    private String result;
    
    @ApiModelProperty("错误信息")
    private String errorMessage;
    
    @ApiModelProperty("错误堆栈")
    private String errorStack;
    
    @ApiModelProperty("处理记录数")
    private Long processedRecords;
    
    @ApiModelProperty("成功记录数")
    private Long successRecords;
    
    @ApiModelProperty("失败记录数")
    private Long failureRecords;
    
    @ApiModelProperty("跳过记录数")
    private Long skippedRecords;
    
    @ApiModelProperty("插入记录数")
    private Long insertRecords;
    
    @ApiModelProperty("更新记录数")
    private Long updateRecords;
    
    @ApiModelProperty("删除记录数")
    private Long deleteRecords;
    
    @ApiModelProperty("数据源记录数")
    private Long sourceRecords;
    
    @ApiModelProperty("目标记录数")
    private Long targetRecords;
    
    @ApiModelProperty("执行进度（百分比）")
    private Integer progress;
    
    @ApiModelProperty("当前步骤")
    private String currentStep;
    
    @ApiModelProperty("总步骤数")
    private Integer totalSteps;
    
    @ApiModelProperty("当前步骤进度")
    private Integer stepProgress;
    
    @ApiModelProperty("执行参数JSON")
    private String parametersJson;
    
    @ApiModelProperty("执行配置JSON")
    private String configJson;
    
    @ApiModelProperty("执行详情JSON")
    private String detailsJson;
    
    @ApiModelProperty("性能指标JSON")
    private String metricsJson;
    
    @ApiModelProperty("触发方式：manual-手动，schedule-定时，api-API调用")
    private String triggerType;
    
    @ApiModelProperty("触发人ID")
    private String triggeredBy;
    
    @ApiModelProperty("触发人姓名")
    private String triggeredByName;
    
    @ApiModelProperty("服务器IP")
    private String serverIp;
    
    @ApiModelProperty("服务器主机名")
    private String serverHostname;
    
    @ApiModelProperty("进程ID")
    private String processId;
    
    @ApiModelProperty("线程ID")
    private String threadId;
    
    @ApiModelProperty("备注")
    private String remark;
    
    @ApiModelProperty("租户ID")
    private String tenantId;
    
    @ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdTime;
    
    // 非数据库字段
    
    @ApiModelProperty("执行参数")
    @TableField(exist = false)
    private Map<String, Object> parameters;
    
    @ApiModelProperty("执行配置")
    @TableField(exist = false)
    private Map<String, Object> config;
    
    @ApiModelProperty("执行详情")
    @TableField(exist = false)
    private Map<String, Object> details;
    
    @ApiModelProperty("性能指标")
    @TableField(exist = false)
    private Map<String, Object> metrics;
    
    @ApiModelProperty("同步任务信息")
    @TableField(exist = false)
    private DataSync syncInfo;
    
    @ApiModelProperty("成功率")
    @TableField(exist = false)
    private Double successRate;
    
    @ApiModelProperty("失败率")
    @TableField(exist = false)
    private Double failureRate;
    
    @ApiModelProperty("处理速度（记录/秒）")
    @TableField(exist = false)
    private Double processSpeed;
    
    @ApiModelProperty("是否正在运行")
    @TableField(exist = false)
    private Boolean running;
    
    @ApiModelProperty("执行时间描述")
    @TableField(exist = false)
    private String durationDesc;
    
    // 业务方法
    
    /**
     * 是否正在运行
     */
    public boolean isRunning() {
        return "running".equals(this.status);
    }
    
    /**
     * 是否执行成功
     */
    public boolean isSuccess() {
        return "success".equals(this.status);
    }
    
    /**
     * 是否执行失败
     */
    public boolean isFailed() {
        return "failed".equals(this.status);
    }
    
    /**
     * 是否已取消
     */
    public boolean isCancelled() {
        return "cancelled".equals(this.status);
    }
    
    /**
     * 获取成功率
     */
    public Double getSuccessRate() {
        if (processedRecords == null || processedRecords == 0) {
            return 0.0;
        }
        if (successRecords == null) {
            return 0.0;
        }
        return (double) successRecords / processedRecords * 100;
    }
    
    /**
     * 获取失败率
     */
    public Double getFailureRate() {
        if (processedRecords == null || processedRecords == 0) {
            return 0.0;
        }
        if (failureRecords == null) {
            return 0.0;
        }
        return (double) failureRecords / processedRecords * 100;
    }
    
    /**
     * 获取处理速度（记录/秒）
     */
    public Double getProcessSpeed() {
        if (duration == null || duration == 0 || processedRecords == null) {
            return 0.0;
        }
        return (double) processedRecords / (duration / 1000.0);
    }
    
    /**
     * 获取状态描述
     */
    public String getStatusDesc() {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case "running": return "运行中";
            case "success": return "成功";
            case "failed": return "失败";
            case "cancelled": return "已取消";
            default: return "未知";
        }
    }
    
    /**
     * 获取触发方式描述
     */
    public String getTriggerTypeDesc() {
        if (triggerType == null) {
            return "未知";
        }
        switch (triggerType) {
            case "manual": return "手动";
            case "schedule": return "定时";
            case "api": return "API调用";
            default: return "未知";
        }
    }
    
    /**
     * 格式化执行时间
     */
    public String formatDuration() {
        if (duration == null) {
            return "0秒";
        }
        
        long seconds = duration / 1000;
        if (seconds < 60) {
            return seconds + "秒";
        }
        
        long minutes = seconds / 60;
        seconds = seconds % 60;
        if (minutes < 60) {
            return minutes + "分" + (seconds > 0 ? seconds + "秒" : "");
        }
        
        long hours = minutes / 60;
        minutes = minutes % 60;
        return hours + "小时" + (minutes > 0 ? minutes + "分" : "") + (seconds > 0 ? seconds + "秒" : "");
    }
    
    /**
     * 计算执行时长
     */
    public void calculateDuration() {
        if (startTime != null && endTime != null) {
            this.duration = java.time.Duration.between(startTime, endTime).toMillis();
        }
    }
    
    /**
     * 计算进度
     */
    public void calculateProgress() {
        if (sourceRecords != null && sourceRecords > 0 && processedRecords != null) {
            this.progress = (int) ((double) processedRecords / sourceRecords * 100);
            if (this.progress > 100) {
                this.progress = 100;
            }
        }
    }
    
    // Getters and Setters
    
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getSyncId() { return syncId; }
    public void setSyncId(String syncId) { this.syncId = syncId; }
    public String getSyncName() { return syncName; }
    public void setSyncName(String syncName) { this.syncName = syncName; }
    public String getBatchNo() { return batchNo; }
    public void setBatchNo(String batchNo) { this.batchNo = batchNo; }
    public LocalDateTime getStartTime() { return startTime; }
    public void setStartTime(LocalDateTime startTime) { this.startTime = startTime; }
    public LocalDateTime getEndTime() { return endTime; }
    public void setEndTime(LocalDateTime endTime) { this.endTime = endTime; }
    public Long getDuration() { return duration; }
    public void setDuration(Long duration) { this.duration = duration; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public String getResult() { return result; }
    public void setResult(String result) { this.result = result; }
    public String getErrorMessage() { return errorMessage; }
    public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
    public String getErrorStack() { return errorStack; }
    public void setErrorStack(String errorStack) { this.errorStack = errorStack; }
    public Long getProcessedRecords() { return processedRecords; }
    public void setProcessedRecords(Long processedRecords) { this.processedRecords = processedRecords; }
    public Long getSuccessRecords() { return successRecords; }
    public void setSuccessRecords(Long successRecords) { this.successRecords = successRecords; }
    public Long getFailureRecords() { return failureRecords; }
    public void setFailureRecords(Long failureRecords) { this.failureRecords = failureRecords; }
    public Long getSkippedRecords() { return skippedRecords; }
    public void setSkippedRecords(Long skippedRecords) { this.skippedRecords = skippedRecords; }
    public Long getInsertRecords() { return insertRecords; }
    public void setInsertRecords(Long insertRecords) { this.insertRecords = insertRecords; }
    public Long getUpdateRecords() { return updateRecords; }
    public void setUpdateRecords(Long updateRecords) { this.updateRecords = updateRecords; }
    public Long getDeleteRecords() { return deleteRecords; }
    public void setDeleteRecords(Long deleteRecords) { this.deleteRecords = deleteRecords; }
    public Long getSourceRecords() { return sourceRecords; }
    public void setSourceRecords(Long sourceRecords) { this.sourceRecords = sourceRecords; }
    public Long getTargetRecords() { return targetRecords; }
    public void setTargetRecords(Long targetRecords) { this.targetRecords = targetRecords; }
    public Integer getProgress() { return progress; }
    public void setProgress(Integer progress) { this.progress = progress; }
    public String getCurrentStep() { return currentStep; }
    public void setCurrentStep(String currentStep) { this.currentStep = currentStep; }
    public Integer getTotalSteps() { return totalSteps; }
    public void setTotalSteps(Integer totalSteps) { this.totalSteps = totalSteps; }
    public Integer getStepProgress() { return stepProgress; }
    public void setStepProgress(Integer stepProgress) { this.stepProgress = stepProgress; }
    public String getParametersJson() { return parametersJson; }
    public void setParametersJson(String parametersJson) { this.parametersJson = parametersJson; }
    public String getConfigJson() { return configJson; }
    public void setConfigJson(String configJson) { this.configJson = configJson; }
    public String getDetailsJson() { return detailsJson; }
    public void setDetailsJson(String detailsJson) { this.detailsJson = detailsJson; }
    public String getMetricsJson() { return metricsJson; }
    public void setMetricsJson(String metricsJson) { this.metricsJson = metricsJson; }
    public String getTriggerType() { return triggerType; }
    public void setTriggerType(String triggerType) { this.triggerType = triggerType; }
    public String getTriggeredBy() { return triggeredBy; }
    public void setTriggeredBy(String triggeredBy) { this.triggeredBy = triggeredBy; }
    public String getTriggeredByName() { return triggeredByName; }
    public void setTriggeredByName(String triggeredByName) { this.triggeredByName = triggeredByName; }
    public String getServerIp() { return serverIp; }
    public void setServerIp(String serverIp) { this.serverIp = serverIp; }
    public String getServerHostname() { return serverHostname; }
    public void setServerHostname(String serverHostname) { this.serverHostname = serverHostname; }
    public String getProcessId() { return processId; }
    public void setProcessId(String processId) { this.processId = processId; }
    public String getThreadId() { return threadId; }
    public void setThreadId(String threadId) { this.threadId = threadId; }
    public String getRemark() { return remark; }
    public void setRemark(String remark) { this.remark = remark; }
    public String getTenantId() { return tenantId; }
    public void setTenantId(String tenantId) { this.tenantId = tenantId; }
    public LocalDateTime getCreatedTime() { return createdTime; }
    public void setCreatedTime(LocalDateTime createdTime) { this.createdTime = createdTime; }
    public Map<String, Object> getParameters() { return parameters; }
    public void setParameters(Map<String, Object> parameters) { this.parameters = parameters; }
    public Map<String, Object> getConfig() { return config; }
    public void setConfig(Map<String, Object> config) { this.config = config; }
    public Map<String, Object> getDetails() { return details; }
    public void setDetails(Map<String, Object> details) { this.details = details; }
    public Map<String, Object> getMetrics() { return metrics; }
    public void setMetrics(Map<String, Object> metrics) { this.metrics = metrics; }
    public DataSync getSyncInfo() { return syncInfo; }
    public void setSyncInfo(DataSync syncInfo) { this.syncInfo = syncInfo; }
    public void setSuccessRate(Double successRate) { this.successRate = successRate; }
    public void setFailureRate(Double failureRate) { this.failureRate = failureRate; }
    public void setProcessSpeed(Double processSpeed) { this.processSpeed = processSpeed; }
    public Boolean getRunning() { return running; }
    public void setRunning(Boolean running) { this.running = running; }
    public String getDurationDesc() { return durationDesc; }
    public void setDurationDesc(String durationDesc) { this.durationDesc = durationDesc; }
}